#include "Dispatcher.h"
#include <stdio.h>
#include <poll.h>
#include <stdlib.h>
#define MAX 1024
struct PollData
{
    int maxfd;
    struct pollfd fds[MAX];
};

//init--初始化
static void* pollInit();
//add
static int pollAdd(struct Channel* Channel, struct EventLoop* eventLoop);
//del
static int pollRemove(struct Channel* Channel, struct EventLoop* eventLoop);
//修改
static int pollModify(struct Channel* Channel, struct EventLoop* eventLoop);
//事件监测
static int pollDispatch(struct EventLoop* eventLoop, int timeout);//单位:s
//清除数据(关闭fd或者释放内存)
static int pollClear(struct EventLoop* eventLoop);

//全局变量
struct Dispatcher PollDispatcher = {
    pollInit,
    pollAdd,
    pollRemove,
    pollModify,
    pollDispatch,
    pollClear
};

//init--初始化
static void* pollInit()
{
    struct PollData* data = (struct PollData*)malloc(sizeof(struct PollData));
    data->maxfd = 0;
    for(int idx = 0; idx < MAX; idx++)
    {
        data->fds[idx].fd = -1;
        data->fds[idx].events = 0;
        data->fds[idx].revents = 0;
    }
    return data;
}

//add
static int pollAdd(struct Channel* Channel, struct EventLoop* eventLoop)
{
    struct PollData* data = (struct PollData*)eventLoop->dispatcherData;
    int events = 0;
    if(Channel->events & ReadEvent)
    {
        events |= POLLIN;
    }
    //这里不能用else，因为读写事件可以同时存在
    if(Channel->events & WriteEvent)
    {
        events |= POLLOUT;
    }
    int idx = 0;
    for(; idx < MAX; idx++)
    {
        if(data->fds[idx].fd == -1)
        {
            data->fds[idx].events = events;
            data->fds[idx].fd = Channel->fd;
            data->maxfd = idx > data->maxfd ? idx : data->maxfd;
            break;
        }
    }
    if(idx >= MAX)//超出监听上限
    {
        return -1;
    }
    return 0;
}
//del
static int pollRemove(struct Channel* Channel, struct EventLoop* eventLoop)
{
    struct PollData* data = (struct PollData*)eventLoop->dispatcherData;
    int idx = 0;
    for(; idx < MAX; idx++)
    {
        if(data->fds[idx].fd == Channel->fd)
        {
            //重置为可用
            data->fds[idx].events = 0;
            data->fds[idx].revents = 0;
            data->fds[idx].fd = -1;
            break;
        }
    }
    //通过channel释放对应的TcpConnection资源
    Channel->destroyCallBack(Channel->arg);
    if(idx >= MAX)//超出监听上限
    {
        return -1;
    }
    return 0;
}
//修改
static int pollModify(struct Channel* Channel, struct EventLoop* eventLoop)
{
    struct PollData* data = (struct PollData*)eventLoop->dispatcherData;
    int events = 0;
    if(Channel->events & ReadEvent)
    {
        events |= POLLIN;
    }
    //这里不能用else，因为读写事件可以同时存在
    if(Channel->events & WriteEvent)
    {
        events |= POLLOUT;
    }
    int idx = 0;
    for(; idx < MAX; idx++)
    {
        if(data->fds[idx].fd == Channel->fd)
        {
            data->fds[idx].events = events;
            break;
        }
    }
    if(idx >= MAX)//超出监听上限
    {
        return -1;
    }
    return 0;
}
//事件监测
static int pollDispatch(struct EventLoop* eventLoop, int timeout)//单位:s
{
    struct PollData* data = (struct PollData*)eventLoop->dispatcherData;
    //             这里的下标范围为有效下标范围，包含maxfd,因此要+1
    int count = poll(data->fds, data->maxfd + 1, timeout * 1000);//S转为MS
    if(count == -1)
    {
        perror("poll");
        exit(0);
    }
    for(int idx = 0; idx <= data->maxfd; idx++)
    {
        if(data->fds[idx].fd == -1)
        {
            continue;
        }
        
        if(data->fds[idx].revents & POLLIN)
        {
            eventActivate(eventLoop, data->fds[idx].fd, ReadEvent);
        }

        if(data->fds[idx].revents & POLLOUT)
        {
            eventActivate(eventLoop, data->fds[idx].fd, WriteEvent);
        }
    }
    return 0;
}
//清除数据(关闭fd或者释放内存)
static int pollClear(struct EventLoop* eventLoop)
{
    struct PollData* data = (struct PollData*)eventLoop->dispatcherData;
    free(data);
    eventLoop->dispatcherData = NULL;
    return 0;
}

